from waveapi import events
from waveapi import robot
from waveapi import element
from waveapi import ops
from waveapi import appengine_robot_runner

import urllib
from google.appengine.api import urlfetch
from xml.dom import minidom

def OnRobotAdded(event, wavelet):
  """Invoked when the robot has been added."""
  badge = 'http://geo-bot.appspot.com/images/geo-bot-badge.png'
  image = element.Image(url=badge, width=220, height=35)
  root_blip = wavelet.root_blip
  new_blip = root_blip.reply()
  new_blip.append(image)
  
  GeoProcess(root_blip)

def OnBlipSubmitted(event, wavelet):
  """Invoked when a blip is sent to the wavelet.
  Gets new blip and passes blip to GeoProcess function"""
  blip = event.blip
  GeoProcess(blip)

def GeoProcess(blip):
  """Send blip information to Yahoo Placemaker via YQL query"""
  contents = blip.text.replace('"', ' ')
  utf_contents = contents.encode('utf-8')
  
  #Set up the form fields for the request to the YQL service
  form_fields = {
    'q': 'SELECT * FROM geo.placemaker WHERE \
    documentContent="' + utf_contents + '" AND documentType="text/plain"',
    'format': 'xml'
  }
  
  #Encode the form data
  form_data = urllib.urlencode(form_fields)

  #Send the requet to YQL API, with encoded form field data
  #If the request is successful, parse and update content in blip
  url = 'http://query.yahooapis.com/v1/public/yql'
  content_type = 'application/x-www-form-urlencoded'
  result = urlfetch.fetch(url = url,
                        payload = form_data,
                        method = urlfetch.POST,
                        headers = {'Content-Type': content_type})
  if result.status_code == 200 and result.content != '':
    dom = minidom.parseString(result.content)
    for node in dom.getElementsByTagName('match'):
      name = node.getElementsByTagName('name')[0].firstChild.data
      woeid = node.getElementsByTagName('woeId')[0].firstChild.data
      latitude = node.getElementsByTagName('latitude')[0].firstChild.data
      longitude = node.getElementsByTagName('longitude')[0].firstChild.data
      references = node.getElementsByTagName('reference')
      
      for reference in references:
        text = reference.getElementsByTagName('text')[0].firstChild.data
        text_start = reference.getElementsByTagName('start')[0].firstChild.data
        text_end = reference.getElementsByTagName('end')[0].firstChild.data
        link = 'http://maps.google.com/maps?q='
        link = link + urllib.quote_plus(text)
        link = link + '&ll=' + latitude + ',' + longitude + 'z=6'
      
        #Check for the 'verbose' mode and append that to blip
        if contents.startswith('\n*'):
          found_text = '\n\n          Found: ' + name + '\n\
          Latitude: ' + latitude + ' | Longitude: ' + longitude + '\n\
          Link: ' + link +'\n\
          Yahoo! Where on Earth (WOE) ID: ' + woeid
          blip.append(found_text)
        
        #Update the blip with hyperlinks  
        blip.range(int(text_start), int(text_end)).annotate\
          ('link/manual', link)
        blip.range(int(text_start), int(text_end)).annotate\
          ('style/fontWeight', 'bold')
        blip.range(int(text_start), int(text_end)).annotate\
          ('style/color', '#CC00FF')

if __name__ == '__main__':
  geoBot = robot.Robot('Geo Bot - The Geo Semantics Bot!', 
      image_url='http://geo-bot.appspot.com/images/icon.png',
      profile_url='http://geo-bot.appspot.com/')
  geoBot.register_handler(events.WaveletSelfAdded, OnRobotAdded)
  geoBot.register_handler(events.BlipSubmitted, OnBlipSubmitted)
  appengine_robot_runner.run(geoBot)